#include"DataStruct.h"
#include "math.h"
#include"core.h"
#include"plane.h"

#include <ctime>
#include <cstdlib>
#include <iostream>
#include <windows.h>

#define PI 3.1415926
#define UNUSED(x) (void)x;
#define random(x) rand() % (x)
#define ACCELERATE_SLOWDOWN 4000
#define WIDTH_WIDGET 2000
#define HEIGHT_WIDGET 1500
#define ACCELERATE_Y 6000

//产生超时故障
void pvp_ai2_timeoutFault()
{
    Sleep(1000);
}

//产生崩溃故障
void pvp_ai2_crashFault()
{
    exit(0);
}

//随机生成故障
void pvp_ai2_randGenFault()
{
    //创建静态初始化标志
    static bool initFlag = false;
    //产生随机数种子
    if (!initFlag)
    {
        srand((int)time(NULL));
        initFlag = true;
    }
    //随机生成故障
    switch (random(3)) {
    case 0:
        pvp_ai2_timeoutFault();
    case 1:
        pvp_ai2_crashFault();
    }
}
int pvp_ai2_aimPlane(DataStruct *data,int &leftward, int &rightward)
{
    double x=data->plane1.x,y=data->plane1.y,cosA,angle_ball,angle;
    cosA=(y-data->plane2.y)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
    angle_ball=acos(cosA)*180/PI;
    angle=fmod(fmod(data->plane2.angle-angle_ball,360)+360,360);
    if(angle<3.6||angle>356.4)
        return 1;
    else if(angle<180)
    {
        leftward=1;
        rightward=0;
    }
    else
    {
        leftward=0;
        rightward=1;
    }
    return 0;
}
int pvp_ai2_aimPlanemov(DataStruct *data,int &leftward, int &rightward)
{
    double x=data->plane1.x,y=data->plane1.y,v_x=data->plane1.v_x,v_y=data->plane1.v_y,v,cosA,sinA,angle_plane,angle;
    v=sqrt(v_x*v_x+v_y*v_y);
    cosA=(v_x*(data->plane2.x-x)+v_y*(data->plane2.y-y))/sqrt((data->plane2.x-x)*(data->plane2.x-x)+(data->plane2.y-y)*(data->plane2.y-y))/v;
    sinA=sqrt(1-cosA*cosA);
    angle_plane=-90-(asin(sinA*v/WIDTH_WIDGET)+atan2(data->plane2.y-y,data->plane2.x-x))*180/PI;
    angle=fmod(fmod(data->plane2.angle-angle_plane,360)+360,360);
    if (angle < 3.6 || angle > 356.4)
    {
        return 1;
    }
    else if (angle < 180)
    {
        leftward = 1;
        rightward = 0;
    }
    else
    {
        leftward = 0;
        rightward = 1;
    }
    return 0;
}

int pvp_ai2_aim(DataStruct *data, BallStruct &ball, int &leftward, int &rightward)
{
    double x=ball.x,y=ball.y,v_x=ball.v_x,v_y=ball.v_y,cosA,sinA,v,angle_ball,angle,l;
    v=sqrt(v_x*v_x+v_y*v_y);
    l=sqrt((data->plane2.x-x)*(data->plane2.x-x)+(data->plane2.y-y)*(data->plane2.y-y));
    if(v>180||l>=20+(data->plane2.r+ball.r))
    {
        cosA=(v_x*(data->plane2.x-x)+v_y*(data->plane2.y-y))/sqrt((data->plane2.x-x)*(data->plane2.x-x)+(data->plane2.y-y)*(data->plane2.y-y))/v;
        sinA=sqrt(1-cosA*cosA);
        angle_ball=-90-(asin(sinA*v/WIDTH_WIDGET)+atan2(data->plane2.y-y,data->plane2.x-x))*180/PI;
        angle=fmod(fmod(data->plane2.angle-angle_ball,360)+360,360);
        if (angle < 3.6 || angle > 356.4)
        {
            return 1;
        }
        else if (angle < 180)
        {
            leftward = 1;
            rightward = 0;
        }
        else
        {
            leftward = 0;
            rightward = 1;
        }
        return 0;
    }
    else
    {
        cosA=(y-data->plane2.y)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
        angle_ball=acos(cosA)*180/PI;
        angle=fmod(fmod(data->plane2.angle-angle_ball,360)+360,360);
        if(angle<3.6||angle>356.4)
            return 1;
        else if(angle<180)
        {
            leftward=1;
            rightward=0;
        }
        else
        {
            leftward=0;
            rightward=1;
        }
        return 0;
    }
}

int pvp_ai2_turn(DataStruct *data,double x,double y,int &leftward,int &rightward)
{
    double cosA,angle_aim,angle;
    cosA=(y-data->plane2.y)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
    angle_aim=acos(cosA)*180/PI;
    angle=fmod(fmod(data->plane2.angle-angle_aim,360)+360,360);
    if(angle<3.6||angle>356.4)
        return 1;
    else if(angle<180)
    {
        leftward=1;
        rightward=0;
        return 0;
    }
    else
    {
        leftward=0;
        rightward=1;
        return 0;
    }
}
void pvp_ai2_location(DataStruct*data,int t,double &x,double &y)
{
    double vx0,vy0,vx1,vy1,a_x,a_y;
    vx0 = data->plane2.v_x;
    vy0 = data->plane2.v_y;
    if(vx0==0&&vy0==0)
    {
        x=data->plane2.x;
        y=data->plane2.y;
    }
    a_x=-vx0/sqrt(vx0*vx0+vy0*vy0)*ACCELERATE_SLOWDOWN;
    a_y=-vy0/sqrt(vx0*vx0+vy0*vy0)*ACCELERATE_SLOWDOWN;
    vx1=vx0+t*a_x/100;
    vy1=vy0+t*a_y/100;
    if(vx1*vx0<0)
        vx1=0;
    if(vy1*vy0<0)
        vy1=0;
    x+=(vx1*vx1-vx0*vx0)/(2*a_x);
    y+=(vy1*vy1-vy0*vy0)/(2*a_y);
}
void pvp_ai2_Move(DataStruct*data,int &des_x,int &des_y,int &leftward,int &rightward,int &forward,int preTime=200)
{
    double min_t = INT_MAX;
    for (int i = 0; i < data->ball_size; i++)
    {
        BallStruct &ball = data->ball[i];
        int xflag,yflag;
        double x = ball.x, y = ball.y, v_x = ball.v_x, v_y = ball.v_y,sinA,tanB,C,l,x1,y1,radC,t,dis,loc_x,loc_y;
        sinA=fabs(x-data->plane2.x)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
        tanB=v_x/v_y;
        if(v_x<0)
        {
            radC=atan(tanB)-asin(sinA);
            xflag=0;
        }
        else
        {
            radC=atan(tanB)+asin(sinA);
            xflag=1;
        }
        if(v_y<0)
        {
            yflag=0;
        }
        else
        {
            yflag=1;
        }
        l=sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y))*sin(radC);
        x1=l*cos(atan(tanB));
        y1=l*sin(atan(tanB));
        C=radC*PI*180;
        t=fabs(x1/v_x)*100;
        if(!(C>=0&&C<=90&&t<preTime))
        {
            continue;
        }
        if(l<data->plane2.r+ball.r+10&&t<min_t)//满足条件，进行移动躲避
        {
            min_t=t;
            des_x = data->plane2.x +  ball.r * x1/ l;
            des_y = data->plane2.y +  ball.r * y1/ l;
            if (des_x < data->plane2.r || des_x > 2000 - data->plane2.r)
            {
                des_x = data->plane2.x;
                if (!yflag)
                    des_y = y1+data->plane2.y + ball.r + data->plane2.r;
                else
                    des_y = y1+data->plane2.y - ball.r - data->plane2.r;
            }
            if (des_y < data->plane2.r || des_y > 1500 - data->plane2.r)
            {
                des_y = data->plane2.y;
                if (xflag)
                    des_x = x1+data->plane2.x + ball.r + data->plane2.r;
                else
                    des_x = x1+data->plane2.x - ball.r - data->plane2.r;
            }
            pvp_ai2_location(data,3000,loc_x,loc_y);
        }
        dis=sqrt((des_x-loc_x)*(des_x-loc_x)+(des_y-loc_y)*(des_y-loc_y));
        if (pvp_ai2_turn(data,des_x,des_y,leftward,rightward))
        {
            forward=0;
        }
        if(dis>=1)
        {
            forward=1;
            leftward=0;
            rightward=0;
        }
    }
}
void pvp_ai2_Shield(DataStruct*data,KeyStruct*key,int PreTime=12)
{
    for (int i = 0; i < data->ball_size; i++)
    {
        BallStruct &ball = data->ball[i];
        double x = ball.x, y = ball.y, v_x = ball.v_x, v_y = ball.v_y,sinA,tanB,C,l,x1,radC,t;
        sinA=fabs(x-data->plane2.x)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
        tanB=v_x/v_y;
        if(v_x<0)
        {
            radC=atan(tanB)-asin(sinA);
        }
        else
        {
            radC=atan(tanB)+asin(sinA);
        }
        l=sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y))*sin(radC);
        x1=l*cos(atan(tanB));
        C=radC*PI*180;
        t=fabs(x1/v_x)*100;
        if(C>=0&&C<=3.6&&t<=PreTime&&l<(data->plane2.r+ball.r))
        {
            key->shield=1;
        }
    }
}
void pvp_ai2_ShieldBullet(DataStruct*data,KeyStruct*key,int PreTime=12)
{
    for (int i = 0; i < data->bullet2_size; i++)
    {
        BulletStruct &bullet = data->bullet2[i];
        double x = bullet.x, y = bullet.y, v_x = bullet.v_x, v_y = bullet.v_y,sinA,tanB,C,l,x1,radC,t;
        sinA=fabs(x-data->plane2.x)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
        tanB=v_x/v_y;
        if(v_x<0)
        {
            radC=atan(tanB)-asin(sinA);
        }
        else
        {
            radC=atan(tanB)+asin(sinA);
        }
        l=sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y))*sin(radC);
        x1=l*cos(atan(tanB));
        C=radC*PI*180;
        t=fabs(x1/v_x)*100;
        if(C>=0&&C<=3.6&&t<=PreTime&&l<(data->plane2.r+bullet.r))
        {
            key->shield=1;
        }
    }
}

void pvp_ai2_MoveforBullet(DataStruct*data,int &des_x,int &des_y,int &leftward,int &rightward,int &forward,int preTime=200)
{
    double min_t = INT_MAX;
    for (int i = 0; i < data->bullet2_size; i++)
    {
        BulletStruct &bullet = data->bullet1[i];
        int xflag,yflag;
        double x = bullet.x, y = bullet.y, v_x = bullet.v_x, v_y = bullet.v_y,sinA,tanB,C,l,x1,y1,radC,t,dis,loc_x,loc_y;
        sinA=fabs(x-data->plane2.x)/sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y));
        tanB=v_x/v_y;
        if(v_x<0)
        {
            radC=atan(tanB)-asin(sinA);
            xflag=0;
        }
        else
        {
            radC=atan(tanB)+asin(sinA);
            xflag=1;
        }
        if(v_y<0)
        {
            yflag=0;
        }
        else
        {
            yflag=1;
        }
        l=sqrt((x-data->plane2.x)*(x-data->plane2.x)+(y-data->plane2.y)*(y-data->plane2.y))*sin(radC);
        x1=l*cos(atan(tanB));
        y1=l*sin(atan(tanB));
        C=radC*PI*180;
        t=fabs(x1/v_x)*100;
        if(!(C>=0&&C<=90&&t<preTime))
        {
            continue;
        }
        if(l<data->plane2.r+bullet.r+10&&t<min_t)//满足条件，进行移动躲避
        {
            min_t=t;
            des_x = data->plane2.x +  bullet.r * x1/ l;
            des_y = data->plane2.y +  bullet.r * y1/ l;
            if (des_x < data->plane2.r || des_x > 2000 - data->plane2.r)
            {
                des_x = data->plane2.x;
                if (!yflag)
                    des_y = y1+data->plane2.y + bullet.r + data->plane2.r;
                else
                    des_y = y1+data->plane2.y - bullet.r - data->plane2.r;
            }
            if (des_y < data->plane2.r || des_y > 1500 - data->plane2.r)
            {
                des_y = data->plane2.y;
                if (xflag)
                    des_x = x1+data->plane2.x + bullet.r + data->plane2.r;
                else
                    des_x = x1+data->plane2.x - bullet.r - data->plane2.r;
            }
            pvp_ai2_location(data,3000,loc_x,loc_y);
        }
        dis=sqrt((des_x-loc_x)*(des_x-loc_x)+(des_y-loc_y)*(des_y-loc_y));
        if (pvp_ai2_turn(data,des_x,des_y,leftward,rightward))
        {
            forward=0;
        }
        if(dis>=1)
        {
            forward=1;
            leftward=0;
            rightward=0;
        }
    }
}
void ai_pvp_ai2(DataStruct*data,KeyStruct*key){
    key->forward = false;
    key->rotate_left = false;
    key->rotate_right = false;
    key->shoot = true;

    static int  des_x, des_y;

    if (data->plane1.v_x==0&&data->plane1.v_y==0)
        //瞄准静止敌机
        pvp_ai2_aimPlane(data,  key->rotate_left, key->rotate_right);

    pvp_ai2_Move(data,des_x,des_y,key->rotate_left, key->rotate_right,key->forward);
    pvp_ai2_Shield(data,key);
    pvp_ai2_ShieldBullet(data,key);
    pvp_ai2_MoveforBullet(data,des_x,des_y,key->rotate_left, key->rotate_right,key->forward);
    if (data->plane1.v_x!=0||data->plane1.v_y!=0)
    {
        //瞄准运动中的敌机
        pvp_ai2_aimPlanemov(data,  key->rotate_left, key->rotate_right);
    }
    if (data->ball_size)
    {
        pvp_ai2_aim(data, data->ball[0], key->rotate_left, key->rotate_right);
    }
}

